#====  PACKAGE =================================================================
#         NAME:  Statistics
#      PURPOSE:  A small collection of methods for statistical analysis of 
#                networks
#   PARAMETERS:  none
#      RETURNS:  true
#===============================================================================

package insj_m_statistics;
use warnings;
use strict;
use Carp;
use base 'Exporter';

our @EXPORT = qw();
our @EXPORT_OK = qw( calculate_eveness, calculate_degree_of_specialisation );
#===  FUNCTION  ================================================================
#         NAME: calculate_conectitiviy
#      PURPOSE: calculates the average connectivity for a given set of nodes
#   PARAMETERS: one or multiple node objects
#      EXAMPLE: my conectivity = calculate_connectivity($node, $node2, $node3);
#      RETURNS: A scalar (float), which descrubes the average connectivity of the given node set. 
#===============================================================================
sub calculate_connectivity {
	
	# Test for all arguments that fulfill the is_node condition.
	# add all scalar(node array/ hash) and average by number of nodes to get 
	# the average connectivity.

	return 1;
	}

#===  FUNCTION  ================================================================
#         NAME: calculate_degree_of_specialism
#      PURPOSE: Calculates the degree of specialisation for a single infection 
#               in one node.
#   PARAMETERS: Node(object)
#      EXAMPLE: my ind_specialism = calculate_degree_of_specialism($node);
#      RETURNS: specialization index (scalar)
#===============================================================================
sub calculate_degree_of_specialisation {
	unless (defined $_[0]->is_node) { carp "Statistic::calculate_degree_of_specialisation requires a node object to be passed! \n"; }
	
	my $sum = 0;
	my @a = $_[0] -> get_state("Adaption");

	# Order @a to automatically get the corresponding rank.
	my @s = sort {$a <=> $b} @a;
	my $i = 0;

	while ( @s ) {
		$i++;
		$sum += $_/( @s * $i );	
		}
	return $sum;
	}

#===  FUNCTION  ================================================================
#         NAME:  calculate_eveness
#      PURPOSE:  Calculates eveness for a set of nodes called by its state.
#   PARAMETERS:  Network(object), State (scalar, scalar)
#      EXAMPLE:  my $eveness = calculate_eveness($network, "class", "plants");
#      RETURNS:  eveness (scalar)
#===============================================================================
sub calculate_eveness {
	unless (defined $_[0]->is_network) { carp "Statistic::calculate_eveness requires a network object to work! \n"; }
	
	my $sum = 0;
	my $a = 0;
	my @list;

	$_[0]->rewind;
	while(my $node = $_[0]->get_next){
		$a += $node->get_number_of_nodes;
		if ($node->get_state($_[1]) eq $_[2]) {
			push(@list, $node->get_name);
			}
		}	

	$a = $a/2;

	for my $p (@list) {
		my $node = $_[0]->get_node($p);
		$sum += $node->get_number_of_nodes/$a * log( $node->get_number_of_nodes/$a ) unless $node->get_number_of_nodes == 0;
		}

	my $eveness = -1 * $sum / log ( scalar @list );

	return $eveness;
}

1;
